<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>作用域和局部作用域</title>
    <script>
        /* 
        作用域和局部作用域

            作用域指一个变量的可见区域

                全局作用域
                    全局作用域在网页时创建，在网页关闭时销毁。
                    所有直接编写在<script><\/script>标签中的代码都位于全局作用域中。
                    全局作用域中的变量是全局变量，可以在任意位置访问。

                局部作用域
                    块作用域是一种局部作用域，块作用域在代码块执行时创建，代码执行时销毁。
                    在块作用域中是局部变量，只能在块内部访问。
        */  

        let a =('全局变量a')

        {
            let b=('局部变量b')

            console.log(b)
            {
                console.log(b)
            }
        }

        console.log(a)
        // console.log(b)      // undefined


//===========================函数作用域=============================================        
        /* 
            函数作用域
                函数作用域也是一种局部作用域
                函数作用域在函数调用时产生，调用结束后销毁。
                函数每次调用都会产生一个新的作用域。
                函数中定义的变量时局部变量，只能在函数内部访问。
        
        */
        const fn=()=>{
            let c='fn中的c'

            console.log(c);     // 函数内部访问
            
        }
        fn()
        fn()
        // console.log(c);         // undefined




//===========================块作用域链=======================================

    /* 
        作用域链
            当我们使用一个变量时，会优先在当前作用域中寻找变量
            如果找到了，则使用
            如果没找到，到上一层作用域中寻找，则使用
            如果没找到，继续到上一层去寻找，以此类推，直到都没找到就会  xx is not undefined

    */
    let d='全局变量d'

    {
        let a= '第一个代码框里的d'
        {
            console.log(d)
        }

    }

//===========================函数作用域链=============================================

    let e=1

    const fn1=()=>{
        let e = 33
            console.log(`函数fn1输出定义的变量`,e)

            const fn2=()=>{
                console.log(`函数fn1嵌套的fn2`,e)
            }
            
            fn2()
    }

    fn1(e)
    </script>   
</head>
<body>
    
</body>
</html>